﻿namespace Autodesk.Revit.UI.Selection;

/// <summary>
/// 自定义的支持多种情况的选择过滤器
/// </summary>
public class SelectionFilter : ISelectionFilter
{
    #region 静态方法

    /// <summary>
    /// 创建支持多种情况的选择过滤器
    /// </summary>
    /// <param name="allowElementFunc"></param>
    /// <param name="allowReferenceFunc"></param>
    /// <returns></returns>
    public static SelectionFilter Create(Func<Element, bool> allowElementFunc, Func<Reference, XYZ, bool> allowReferenceFunc)
        => new SelectionFilter(allowElementFunc, allowReferenceFunc);

    /// <summary>
    /// 创建支持多种情况的选择过滤器
    /// </summary>
    /// <param name="allowElementFunc"></param>
    /// <returns></returns>
    public static SelectionFilter Create(Func<Element, bool> allowElementFunc) => new SelectionFilter(allowElementFunc);

    /// <summary>
    /// 创建支持多种情况的选择过滤器
    /// </summary>
    /// <param name="allowReferenceFunc"></param>
    /// <returns></returns>
    public static SelectionFilter Create(Func<Reference, XYZ, bool> allowReferenceFunc) => new SelectionFilter(allowReferenceFunc);

    /// <summary>
    /// 创建一个根据类型筛选的选择器
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static SelectionFilter CreateOfType(Type type) => Create(e => e.GetType() == type);

    /// <summary>
    /// 创建一个根据类型筛选的选择器
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static SelectionFilter CreateOfType<T>() => Create(e => e is T);

    #endregion 静态方法

    /// <summary>
    /// 实例化
    /// </summary>
    /// <param name="allowElementFunc"></param>
    /// <param name="allowReferenceFunc"></param>
    public SelectionFilter(Func<Element, bool> allowElementFunc, Func<Reference, XYZ, bool> allowReferenceFunc)
    {
        AllowElementFunc = allowElementFunc;
        AllowReferenceFunc = allowReferenceFunc;
    }

    /// <summary>
    /// 实例化
    /// </summary>
    /// <param name="allowElementFunc"></param>
    public SelectionFilter(Func<Element, bool> allowElementFunc) : this(allowElementFunc, (_, _) => true)
    {
    }

    /// <summary>
    /// 实例化
    /// </summary>
    /// <param name="allowReferenceFunc"></param>
    public SelectionFilter(Func<Reference, XYZ, bool> allowReferenceFunc) : this(_ => true, allowReferenceFunc)
    {
    }

    /// <summary>
    ///
    /// </summary>
    public Func<Element, bool> AllowElementFunc { get; }

    /// <summary>
    ///
    /// </summary>
    public Func<Reference, XYZ, bool> AllowReferenceFunc { get; }

    /// <summary>
    ///
    /// </summary>
    /// <param name="elem"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public bool AllowElement(Element elem) => AllowElementFunc(elem);

    /// <summary>
    ///
    /// </summary>
    /// <param name="reference"></param>
    /// <param name="position"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public bool AllowReference(Reference reference, XYZ position) => AllowReferenceFunc(reference, position);
}
